# !/usr/bin/env python3
# -*- coding: utf-8 -*-

from lib.tsn_builder_lib import host_to_net
import xml.etree.ElementTree as EleTree

from tsn_builder_struct.gcl_tbl_structure import GCLTbl, GCLEachPort, GCLEachNode


def link_gcl_tbl(node,
                 gcl_set,
                 reg_addr):
    # 找到该节点对应的GCL门控表
    node_id = node['src_node']
    tbl_each_node = []
    for tbl in gcl_set.tbl_set:
        if tbl.node_id == node_id:
            tbl_each_node = tbl
            break

    if not tbl_each_node:
        return []

    dic = []

    gcl_set = tbl_each_node.gcl

    for gcl_each_port in gcl_set:
        port_id = gcl_each_port.port_id
        addr = reg_addr.gcl_tbl[port_id]['addr']
        value_set = []
        gcl = gcl_each_port.gate_each_port
        for state in gcl:
            state_str = host_to_net(state)
            if len(value_set) == 359:
                addr_str = host_to_net(addr)
                dic.append({'addr': addr_str,
                            'value': value_set})
                addr = addr + 360
                value_set = []
            value_set.append(state_str)
        if value_set:
            addr_str = host_to_net(addr)
            dic.append({'addr': addr_str,
                        'value': value_set})
    return dic


def _get_gcl_tbl(gcl_tbl_xml):
    gcl_set = []

    root = EleTree.parse(gcl_tbl_xml)
    node_ele_set = root.findall('node')
    for node_ele in node_ele_set:
        gcl_dic = {}
        node_id = node_ele.findtext('node_id')
        gcl_dic.update({'node_id': int(node_id)})

        port_ele_set = node_ele.findall('port')
        port_num = 0
        for port_ele in port_ele_set:
            gate_ele_set = port_ele.findall('entry')
            gate_set = []
            for i in range(len(gate_ele_set)):
                gate_ele = gate_ele_set[i].findtext('gate')
                gate_set.append(int(gate_ele, 2))
            port_name = 'gcl_port%d' % port_num
            gcl_dic.update({port_name: gate_set})
            port_num += 1
        for port in range(port_num, 20):
            port_name = 'gcl_port%d' % port
            gcl_dic.update({port_name: []})
        gcl_set.append(gcl_dic)

    return gcl_set


def _init_gcl_tbl(gcl_set):
    gcl_tbl = GCLTbl()
    for each_node in gcl_set:
        gcl = []
        for port in range(20):
            port_index = 'gcl_port%d' % port
            if each_node[port_index]:
                gcl_each_port = GCLEachPort(port, each_node[port_index])
                gcl.append(gcl_each_port)
            elif not each_node[port_index]:
                pass
        gcl_each_node = GCLEachNode(each_node['node_id'],
                                    gcl)
        gcl_tbl.append_gcl_each_node(gcl_each_node)

    return gcl_tbl


def read_gcl_tbl(gcl_tbl_xml):
    gcl_set = _get_gcl_tbl(gcl_tbl_xml)
    # print('DEBUG')
    # [print(entry) for entry in gcl_set]

    gcl_tbl = _init_gcl_tbl(gcl_set)

    return gcl_tbl


def main():
    gcl_tbl_xml = '../output_xml/tbl_xml/gcl_tbl.xml'
    read_gcl_tbl(gcl_tbl_xml)


if __name__ == '__main__':
    main()
